(ns ura.Role
  (:require
   [reagent.core :as r]
   [reagent.dom :as rd]
   [ajax.core :refer [GET POST PUT DELETE]]

   [taoensso.telemere :as t]

   [ura.common :as uc :refer [log spy]]
   [ura.config :refer [getUrl]]
   [ura.ui :as ui]
   [ura.table :refer [MyTable]]
   [ura.style :as sty :refer [attr]]
   [ura.select :refer [my-select]]

   [re-com.core :as rc :refer [at tree-select tree-select-dropdown]]
   ))

(def tableData (r/atom {:data []}))
(def dataItem (r/atom {:authIds #{}}))
(def editModal (r/atom false))
(def authList (r/atom []))

(defn loadAuthList []
  (GET (getUrl "/ura/auth")
       {
        :response-format :json
        :keywords? true
        :handler
        (fn [resp]
          (reset! authList (map (fn [a] (assoc a :group [(:category a)])) resp))
          (t/log! {:id "test1" :data @authList} "Role.cljs get auth list")
          )}))


(defn loadData [& param]
  (let [p (js->clj param)]
  (t/log! ["Role.cljs query role data " p])
  (GET (getUrl "/ura/role")
       {:params p
        :response-format :json
        :keywords? true
        :handler
        (fn [resp]
          (let [newData (doall (mapv (fn [r]
                               (let [ids (set (map :id (:authInfoList r)))]
                                 (assoc r :authIds ids)                                
                                 )
                               ) resp))]
            (t/log! {:data newData} "Role.cljs get role resp ")
            (swap! tableData assoc :data newData)
            )
          )
        })
    )
  )

(defn saveItem [data]
  (let [method (if (nil? data.id) POST PUT)]
    (t/log! {:data [method data]} "save role data ")
    (method (getUrl "/ura/role")
            {
             :headers {:content-type "application/json"}
             :body (js/JSON.stringify (clj->js data))
             :handler (fn [resp]
                        (log " roleInfo " resp)
                        )
             :error-handler (fn [resp]
                              (log "error " resp)
                              ;; TODO show erro message
                              )
             :finally (fn []
                        (reset! editModal false)
                        (loadData)
                        )
             })
    )
  )


(defn callDelete [data]
  (DELETE (getUrl (str "/ura/role/" (:id data)))
          {:handler (fn [resp]
                      (loadData)
                      (log "delete data" resp)
                      )
           }))
;;; ui

(defn handleNewItem []
  (reset! editModal true)
  (reset! dataItem {:authIds #{}})
  )

(defn handleEdit [row value]
  (reset! dataItem row)
  (reset! editModal true)
  )


(defn editModel []
  (fn []
    (when @editModal
      [rc/modal-panel {
                       :backdrop-on-click #(reset! editModal nil)
                       :child [:div.box {}
                               [:span "添加角色"]
                               [:div
                                [ui/MyFormField {:label "名称" :required true}
                                 [ui/MyInput {:model (r/cursor dataItem [:name])} ]
                                 ]
                                [ui/MyFormField {:label "编码" :required true}
                                 [ui/MyInput {:model (r/cursor dataItem [:code])} ]
                                 ]
                                [ui/MyFormField {:label "说明" :required true}
                                 [ui/MyInput {:model (r/cursor dataItem [:description])} ]
                                 ]
                                [ui/MyFormField {:label "权限" :required true}
                                 [rc/tree-select-dropdown {:src (at)
                                                           :choices @authList
                                                           :id-fn :id
                                                           :label-fn :name
                                                           :model (r/cursor dataItem [:authIds])
                                                           :on-change #(swap! dataItem assoc :authIds %)
                                                           :width "250px"
                                                           }]
                                 ]
                                ]
                               
                               [:div (attr :flex :jc-e :gap=15)
                                [:button.btn {:on-click #(reset! editModal nil)} "取消"]
                                [:button.btn.btn-primary {:on-click #(saveItem @dataItem)} "确定"]
                                ]
                               ]
                       }
       ]
      )
    )
  )


(defn searchForm []
  (let [searchParam (r/atom {})]
    (fn []
      [:div (attr :flex :justify=end :gap=5)
       [ui/my-label "名称："]
       [ui/MyInput {:model (r/cursor searchParam [:name])}]
       [ui/my-label "编码："]
       [ui/MyInput {:model (r/cursor searchParam [:code])}]
       
       [:button.btn.btn-primary (attr {:on-click #(loadData @searchParam)})
        [:i.fa.fa-search.mr-2] "查询"]
       [:button.btn.btn-primary (attr {:on-click #(do (reset! searchParam {}) (loadData))})
        [:i.fa.fa-rotate-right.mr-2] "重置"]
       ]
      )
    )
  )

;; Top tool bar
(defn topBar []
  [ui/my-toolbar (attr :jc-b)
   [:button.btn.btn-primary (attr {:on-click handleNewItem}) "添加角色"]
   [searchForm]
   ]
  )


;; (defn handleSelect [keys rows]
;;   (log "select row: " keys rows)
;;   (let [selected (js->clj rows :keywordize-keys true)]
;;     (ant/message.info (str "You have selected: " (map :name selected)))
;;     )
;;   )


(defn datatable []
  [MyTable {
            :data @(r/cursor tableData [:data])
            :striped true
            :fullwidth true
            :hoverable true
            :row-key "id"
            :columns [
                      {:title "编号" :prop "id"}
                      {:title "名称" :prop :name :sorter #(uc/comparison %1 %2 :name)}
                      {:title "编码" :prop "code" :sorter #(uc/comparison %1 %2 :code)}
                      {:title "权限" :prop "authInfoList"
                       :render (fn [row value]
                                 (->> (map :name value) (clojure.string/join ","))
                                 )}
                      {:title "说明" :prop "description"}
                      {:title "操作" :width "200px"
                       :render (fn [row value]
                                 (let [delpop (r/atom false)
                                       closepop #(reset! delpop false)
                                       ]
                                 [:div (attr :flex :gap=5)
                                  [rc/popover-anchor-wrapper :src (rc/at)
                                   :showing? delpop
                                   :position :below-center
                                   :anchor [:button.btn.btn-sm {:on-click #(reset! delpop true)} "删除" ]
                                   :popover [rc/popover-content-wrapper :src (rc/at)
                                             :width "300px"
                                             :backdrop-opacity 0.3
                                             :on-cancel closepop
                                             :title "是否删除数据？ "
                                             :close-button? true
                                             :body [:div
                                                    [:span {} (:name value)]
                                                    [:div (attr :flex :jc-e :gap=10)
                                                     [:button.btn {:on-click closepop} "取消"]
                                                     [:button.btn.btn-primary {:on-click #(callDelete value)} "确定"]
                                                     ]]]]
                                  [:button.btn.btn-sm
                                   {:on-click #(handleEdit row value)} "编辑"]
                                  
                                  ]))}]
            :page {:current 1 :pageSize 10 :pageSizeItem [10, 20, 50, 100]}

    }])

(defn genPage []
  (loadAuthList)
  (loadData)
  [:div
   [editModel]
   [topBar]
   [datatable]
   ]
)
